<template>
  <view
    class="w-full h-full bg-green"
    @touchstart.stop.prevent="handleTouchStart"
    @touchmove.stop.prevent="handleTouchMove"
    @touchend.stop.prevent="handleTouchEnd"
  >
    <canvas
      id="trailCanvas"
      ref="trailCanvas"
      class="canvas"
      type="2d"
      style="width: 100%; height: 100%; position: absolute; top: 0; left: 0;"
    ></canvas>
  </view>
</template>

<script setup>
import { nextTick, ref, onMounted, getCurrentInstance } from "vue";
import { str2ab } from "../../utils/index";
import { throttle } from "lodash";
import { onLoad } from "@dcloudio/uni-app";

let list = [
  "0x01",
  "0x02",
  "0x03",
  "0x04",
  "0x05",
  "0x06",
  "0x07",
  "0x08",
  "0x09",
];

const x = ref(0);
const y = ref(0);

// 触摸开始事件
const handleTouchStart = (event) => {
  console.log('触摸开始事件触发');
  if (!event.touches || event.touches.length === 0) return;

  const touch = event.touches[0];
  x.value = touch.clientX;
  y.value = touch.clientY;
  // 清空之前的轨迹
  trailPoints.value = [];
  // 添加起始点
  trailPoints.value.push({ x: x.value, y: y.value });
  drawTrail();
};

// 触摸结束事件
const handleTouchEnd = () => {
  console.log('触摸结束事件触发');
  // 可以在这里添加一些收尾工作
};



const trailCanvas = ref(null);
const ctx = ref(null);
const canvasWidth = ref(0);
const canvasHeight = ref(0);
const trailPoints = ref([]); // 保留轨迹点数组用于绘制

const lastMsg = ref("");
const lastSpeed = ref(0);

// 初始化Canvas
onMounted(() => {
  console.log('onMounted 执行');
  // 尝试多次获取Canvas，防止初始化时机问题
  let retryCount = 0;
  const maxRetries = 5;
  const retryInterval = 200;

  const initCanvas = () => {
    console.log(`尝试初始化Canvas (${retryCount + 1}/${maxRetries})`);
    // 获取canvas元素
    const query = uni.createSelectorQuery().in(getCurrentInstance());
    query.select('#trailCanvas')
      .fields({ node: true, size: true })
      .exec((res) => {
        console.log('查询canvas结果:', res);
        if (!res || !res[0]) {
          console.error('未找到canvas元素');
          retryCount++;
          if (retryCount < maxRetries) {
            console.log(`将在${retryInterval}ms后重试`);
            setTimeout(initCanvas, retryInterval);
          }
          return;
        }

        const canvas = res[0].node;
        if (!canvas) {
          console.error('获取到的canvas节点为空');
          retryCount++;
          if (retryCount < maxRetries) {
            console.log(`将在${retryInterval}ms后重试`);
            setTimeout(initCanvas, retryInterval);
          }
          return;
        }

        const ctx = canvas.getContext('2d');
        if (!ctx) {
          console.error('无法获取canvas上下文');
          retryCount++;
          if (retryCount < maxRetries) {
            console.log(`将在${retryInterval}ms后重试`);
            setTimeout(initCanvas, retryInterval);
          }
          return;
        }

        console.log('获取canvas上下文成功');

        // 设置canvas尺寸
        canvas.width = res[0].width;
        canvas.height = res[0].height;
        console.log(`设置canvas尺寸: ${canvas.width}x${canvas.height}`);

        // 存储canvas和context
        trailCanvas.value = canvas;
        ctx.value = ctx;

        // 设置基础绘图样式
        ctx.value.lineCap = "round";  // 圆角线条末端
        ctx.value.lineJoin = "round"; // 圆角线条连接
        // 后续在绘制时动态设置strokeStyle和lineWidth以实现毛笔效果

        // 更新canvas尺寸数据
        canvasWidth.value = res[0].width;
        canvasHeight.value = res[0].height;
      });
  };

  // 立即尝试初始化
  initCanvas();
});

const handleTouchMove = throttle((event) => {
  console.log('触摸移动事件触发');
  // 防止冒泡和默认行为
  event.stopPropagation();
  event.preventDefault();

  if (!event.touches || event.touches.length === 0) {
    console.error('没有触摸点');
    return;
  }

  const touch = event.touches[0];
  const currentX = touch.clientX;
  const currentY = touch.clientY;
  console.log(`触摸坐标: X=${currentX}, Y=${currentY}`);

  // 计算值差
  let diffX = currentX - x.value;
  let diffY = currentY - y.value;

  diffX = Math.abs(diffX);
  diffY = Math.abs(diffY);

  let speed = parseInt((diffX + diffY) % 9);
  speed = speed < 0 ? 9 + speed : speed;

  handleShake(speed);

  // 更新坐标
  x.value = currentX;
  y.value = currentY;

  // 添加当前点到轨迹数组
  trailPoints.value.push({ x: currentX, y: currentY });
  console.log(`添加轨迹点，当前轨迹点数量: ${trailPoints.value.length}`);
  // 限制轨迹点数量
  if (trailPoints.value.length > 30) {
    trailPoints.value.shift();
  }

  // 绘制轨迹
  drawTrail();
}, 30); // 增加节流时间到30ms

// 绘制轨迹的方法
const drawTrail = () => {
  console.log('开始绘制轨迹');
  if (!ctx.value) {
    console.error('Canvas上下文未初始化');
    // 如果上下文未初始化，尝试重新初始化
    if (trailCanvas.value) {
      console.log('尝试重新获取Canvas上下文');
      ctx.value = trailCanvas.value.getContext('2d');
      if (ctx.value) {
        console.log('重新获取Canvas上下文成功');
        // 重新设置基础绘图样式
        ctx.value.lineCap = "round";
        ctx.value.lineJoin = "round";
      } else {
        console.error('重新获取Canvas上下文失败');
        return;
      }
    } else {
      return;
    }
  }

  if (!trailPoints.value.length) {
    console.log('没有轨迹点可绘制');
    return;
  }

  // 清除画布
  ctx.value.clearRect(0, 0, canvasWidth.value, canvasHeight.value);
  console.log(`清除画布: ${canvasWidth.value}x${canvasHeight.value}`);

  if (trailPoints.value.length > 1) {
    console.log(`绘制${trailPoints.value.length}个点的轨迹`);

    // 为每个线段创建渐变和调整线宽
    for (let i = 1; i < trailPoints.value.length; i++) {
      const prev = trailPoints.value[i - 1];
      const curr = trailPoints.value[i];

      // 计算两点之间的距离（用于确定线宽）
      const dx = curr.x - prev.x;
      const dy = curr.y - prev.y;
      const distance = Math.sqrt(dx * dx + dy * dy);

      // 根据距离调整线宽（改进版：更平滑的粗细变化）
      let lineWidth = 15 - Math.min(10, distance / 8);
      lineWidth = Math.max(4, lineWidth); // 最小线宽为4
      // 添加微小的随机波动，增加自然感
      lineWidth += (Math.random() * 2 - 1);

      // 创建更美观的渐变色（紫色到蓝绿色）
      const gradient = ctx.value.createLinearGradient(prev.x, prev.y, curr.x, curr.y);
      gradient.addColorStop(0, "rgba(120, 50, 220, 0.9)");  // 深紫色
      gradient.addColorStop(0.4, "rgba(80, 100, 230, 0.8)"); // 蓝色
      gradient.addColorStop(1, "rgba(50, 180, 200, 0.7)");  // 蓝绿色

      // 设置当前线段的样式
      ctx.value.strokeStyle = gradient;
      ctx.value.lineWidth = lineWidth;

      // 绘制线段
      ctx.value.beginPath();
      ctx.value.moveTo(prev.x, prev.y);
      // 使用贝塞尔曲线让线条更平滑
      // 改进的控制点算法，使曲线更自然
      const midX = (prev.x + curr.x) / 2;
      const midY = (prev.y + curr.y) / 2;
      // 计算垂直于线段的方向
      const perpendicularX = -(curr.y - prev.y) * 0.15; // 0.15为弯曲程度系数
      const perpendicularY = (curr.x - prev.x) * 0.15;
      // 添加随机因素，但控制在合理范围内
      const randomFactor = (Math.random() * 8 - 4);
      const controlX = midX + perpendicularX + randomFactor;
      const controlY = midY + perpendicularY + randomFactor;
      ctx.value.quadraticCurveTo(controlX, controlY, curr.x, curr.y);
      ctx.value.stroke();
    }

    console.log('轨迹绘制完成');
  }
  // 对于单个点，绘制一个小圆点
  else if (trailPoints.value.length === 1) {
    const point = trailPoints.value[0];
    console.log(`绘制单个点: X=${point.x}, Y=${point.y}`);

    // 创建更美观的径向渐变
    const gradient = ctx.value.createRadialGradient(
      point.x, point.y, 0,
      point.x, point.y, 10
    );
    gradient.addColorStop(0, "rgba(120, 50, 220, 0.9)");  // 深紫色
    gradient.addColorStop(0.5, "rgba(80, 100, 230, 0.8)"); // 蓝色
    gradient.addColorStop(0.8, "rgba(50, 180, 200, 0.3)");  // 蓝绿色（半透明）
    gradient.addColorStop(1, "rgba(50, 180, 200, 0)");    // 完全透明

    ctx.value.beginPath();
    // 稍微椭圆的形状，更自然
    ctx.value.ellipse(point.x, point.y, 10, 8, 0, 0, Math.PI * 2);
    ctx.value.fillStyle = gradient;
    ctx.value.fill();
    console.log('单点绘制完成');
  }
};

const timeout = ref(null);

// 处理摇一摇事件
const handleShake = throttle((speed) => {
  lastSpeed.value = speed;

  let msg = list[speed];

  if (msg === lastMsg.value) {
    return;
  }

  sendVibrationMode(msg);

  lastMsg.value = msg;
}, 1000);

const sendVibrationMode = (msg) => {
  // 向蓝牙设备发送一个0x00的16进制数据

  return new Promise((resolve, reject) => {
    let buffer = str2ab(msg);

    uni.writeBLECharacteristicValue({
      deviceId: deviceId.value,
      serviceId: serviceId.value,
      characteristicId: characteristicId.value,
      value: buffer,
      writeType: "write",
      success(res) {
        resolve(res);

        timeout.value = setTimeout(() => {
          sendVibrationMode("0x00");
        }, 1000);
      },
      fail(err) {
        reject(err);
      },
    });
  });
};

const deviceId = ref("");
const serviceId = ref("");
const characteristicId = ref("");
const name = ref("");
const advertisServiceUUIDs = ref([]);

onLoad(() => {
  deviceId.value = uni.getStorageSync("deviceId") || "";
  serviceId.value = uni.getStorageSync("serviceId") || "";
  characteristicId.value = uni.getStorageSync("characteristicId") || "";
  name.value = uni.getStorageSync("name") || "";
  advertisServiceUUIDs.value = uni.getStorageSync("advertisServiceUUIDs") || [];
});
</script>

<style lang="scss" scoped>
.top {
  z-index: 99999;
}

.w-full {
  width: 100vw;
}

.h-full {
  height: calc(100vh - 44px);
}

.bg-green {
  background-color: aquamarine;
}

.trail-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: calc(100vh - 44px);
  pointer-events: none;
  z-index: 9999;
}

.trail-point {
  position: absolute;
  width: 20px;
  height: 20px;
  background-color: #cd1300;
  border-radius: 50%;
  // transition: opacity 0.5s ease-out;
}

// 添加Canvas样式
.canvas {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none; // 确保Canvas不阻碍触摸事件
  z-index: 9999;
}
</style>
